#ifndef _Z_BT_CONN_MGR_H
#define _Z_BT_CONN_MGR_H

#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/addr.h>

/* 定义支持的最大连接数 */
#define CONN_MGR_MAX_CONN 8

/**
 * @brief 连接状态枚举
 */
typedef enum {
    CONN_STATE_DISCONNECTED = 0,
    CONN_STATE_CONNECTED,      /* 连接已建立 */
    CONN_STATE_DISCOVERING,    /* 正在进行 GATT 服务/特征发现 */
    CONN_STATE_READY           /* 连接及 GATT cache 均就绪 */
} conn_state_t;

/**
 * @brief 连接发现完成后的回调函数
 *
 * @param conn 蓝牙连接
 * @param err  0 表示成功，其它为失败码
 */
typedef void (*conn_discovery_cb_t)(struct bt_conn *conn, int err);

/**
 * @brief 每个连接的管理对象，整合了蓝牙连接信息以及 GATT cache 数据
 *
 * 内部包含服务发现时需要缓存的所有句柄与状态。
 */
struct bt_conn_mgr {
    struct bt_conn *conn;
    bt_addr_le_t remote_addr; /* 存储远程设备地址 */
    conn_state_t state;
    /* 以下字段用于存储 GATT 服务发现结果 */
    uint16_t start_handle;
    uint16_t end_handle;
    uint16_t write_handle;
    uint16_t notify_handle;
    uint16_t ccc_handle;
    bool discovered;
    bool char_discovery_done;
    bool desc_discovery_in_progress;
    struct bt_gatt_subscribe_params subscribe_params;
    struct bt_gatt_write_params write_params;
};

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 初始化连接管理模块
 */
void bt_conn_mgr_init(void);

/**
 * @brief 添加一个连接管理对象（内部同时保存远程设备地址）
 *
 * @param conn 蓝牙连接
 * @return 0 成功，负值错误码表示失败
 */
int bt_conn_mgr_add(struct bt_conn *conn);

/**
 * @brief 移除指定连接的管理对象
 *
 * @param conn 蓝牙连接
 * @return 0 成功，负值错误码表示失败
 */
int bt_conn_mgr_remove(struct bt_conn *conn);

/**
 * @brief 根据 bt_conn 获取连接管理对象
 *
 * @param conn 蓝牙连接
 * @return 指向连接管理对象的指针，未找到返回 NULL
 */
struct bt_conn_mgr *bt_conn_mgr_get(struct bt_conn *conn);

/**
 * @brief 根据远程设备的 MAC 地址字符串获取连接管理对象
 *
 * @param mac_str 设备的 MAC 地址字符串，例如 "AA:BB:CC:DD:EE:FF"
 * @return 指向连接管理对象的指针，未找到返回 NULL
 */
struct bt_conn_mgr *bt_conn_mgr_get_by_mac(const char *mac_str);

/**
 * @brief 发起 GATT 服务/特征/描述符发现（集成在连接管理中）
 *
 * 该函数通过指定的服务 UUID 发起发现，内部自动查找写特征、notify 特征及其 CCC 描述符，
 * 并更新管理对象中的对应句柄。上层通过回调获知发现结果，成功时状态更新为 CONN_STATE_READY。
 *
 * @param conn    蓝牙连接
 * @param svc_uuid 要发现的服务 UUID
 * @param cb      发现完成后的回调
 * @return 0 成功，负值错误码表示失败
 */
int bt_conn_mgr_discover(struct bt_conn *conn, const struct bt_uuid *svc_uuid,
                         conn_discovery_cb_t cb);

/**
 * @brief 通过指定连接发送数据（基于发现到的写特征）
 *
 * @param conn 蓝牙连接
 * @param data 数据缓冲区
 * @param len  数据长度
 * @return 0 成功，负值错误码表示失败
 */
int bt_conn_mgr_send_data(struct bt_conn *conn, const uint8_t *data, uint16_t len);

/**
 * @brief 使能或禁用指定连接的 notify（基于发现到的 notify 特征及 CCC 描述符）
 *
 * @param conn     蓝牙连接
 * @param enable   true 使能 notify，false 禁用 notify（订阅取消）
 * @param notify_cb notify 回调函数，传 NULL 则使用默认回调
 * @return 0 成功，负值错误码表示失败
 */
int bt_conn_mgr_notify_enable(struct bt_conn *conn, bool enable, bt_gatt_notify_func_t notify_cb);

/**
 * @brief 重置指定连接的 GATT cache 数据（集成在连接管理对象中）
 *
 * @param conn 蓝牙连接
 */
void bt_conn_mgr_reset(struct bt_conn *conn);

/* 以下为新增包装接口，支持以 MAC 地址作为参数进行操作 */

/**
 * @brief 通过 MAC 地址发起 GATT 服务发现
 *
 * @param mac_str  设备的 MAC 地址字符串
 * @param svc_uuid 要发现的服务 UUID
 * @param cb       发现完成回调
 * @return 0 成功，负值错误码表示失败
 */
int bt_conn_mgr_discover_by_mac(const char *mac_str, const struct bt_uuid *svc_uuid,
                                conn_discovery_cb_t cb);

/**
 * @brief 通过 MAC 地址发送数据
 *
 * @param mac_str 设备的 MAC 地址字符串
 * @param data    数据缓冲区
 * @param len     数据长度
 * @return 0 成功，负值错误码表示失败
 */
int bt_conn_mgr_send_data_by_mac(const char *mac_str, const uint8_t *data, uint16_t len);

/**
 * @brief 通过 MAC 地址使能或禁用 notify
 *
 * @param mac_str  设备的 MAC 地址字符串
 * @param enable   true 使能 notify，false 禁用 notify
 * @param notify_cb notify 回调函数，传 NULL 则使用默认回调
 * @return 0 成功，负值错误码表示失败
 */
int bt_conn_mgr_notify_enable_by_mac(const char *mac_str, bool enable, bt_gatt_notify_func_t notify_cb);

#ifdef __cplusplus
}
#endif

#endif /* _Z_BT_CONN_MGR_H */
